import unittest

import math, operator
from functools import reduce

#the smallest number divisible by each numbers to 1 to 20
def get_prime_factors(n):
	factors = []
	factor = 2
	while factor <= n:
		if n%factor==0:
			factors.append(factor)
			n /= factor
		else: factor+=1
	return factors

def get_max_count(l):
	'''take a list of list and return a dictionary with each element of sub-list as key and max frequency as value'''
	fs = {}
	for il in l:
		for i in il:
			if fs.get(i, 0) < il.count(i): fs[i] = il.count(i)
	return fs

def is_prime(n):
	sq = int(math.sqrt(n)+1)
	return not [i for i in range(2,sq) if n%i==0]


class test_primes_factors(unittest.TestCase):
	def test_zeros(self):
		self.assertTrue(\
			get_prime_factors(0)==[] and get_prime_factors(1)==[])
	def test_primes(self):
		for i in range(3, 500):
			if is_prime(i)==True:
				self.assertTrue(get_prime_factors(i)==[i], "test_primes: {0} not == {1}".format(get_prime_factors(i), [i]) )

class test_get_max_count(unittest.TestCase):
	def test_repetition(self):
		k = 50
		k1 = 2
		l = [[k1 for i in range(j)] for j in range(k)]
		self.assertTrue(get_max_count(l)=={k1:k-1}, "test max count:{0} should be {1}".format(get_max_count(l), k-1)) 


if __name__ == "__main__":
	#unittest.main()	

	f = lambda x: operator.pow(x[0], x[1])
	l = [get_prime_factors(i) for i in [i for i in range(1,21)]]
	d = get_max_count(l)
	result = reduce( operator.mul, [f(i) for i in d.items()] )	
	print(result)
